import 'package:flutter/material.dart';
import 'package:lib_core/lib_core.dart';
import 'package:lib_core/logger/destination/gt_logger_base_destination.dart';
import 'package:lib_core/logger/destination/gt_logger_console_destination.dart';
import 'package:lib_core/logger/destination/gt_logger_recovery_destination.dart';
import 'package:lib_core/logger/filter/gt_logger_sensitive_words_filter.dart';
import 'gt_logger_model.dart';

/// Author: Shper
/// Created: 2023/9/22
class GTLogger {

  /// 日志等级
  /// [verbose] 详细信息
  /// [debug] 调试信息
  /// [info] 常规信息
  /// [warning] 警告
  /// [error] 错误
  static GTLoggerLevel level = GTLoggerLevel.verbose;

  static final List<GTLoggerBaseDestination> destinations = [];

  /// 日志库初始化
  static void setup() {
    /// 添加控制台目的源
    var consoleDestination = GTLoggerConsoleDestination();
    // 添加敏感词过滤器
    consoleDestination.addFilter(GTLoggerSensitiveWordsFilter());
    addDestination(consoleDestination);

    /// 添加日志回捞目的源
    addDestination(GTLoggerRecoveryDestination());
  }

  /// 添加日志输出源
  static void addDestination(GTLoggerBaseDestination destination) {
    destinations.add(destination);
  }

  /// Short
  static void v(Object object) => verbose(object);

  static void d(Object object) => debug(object);

  static void i(Object object, {bool isRecovery = true}) => info(object, isRecovery: isRecovery);

  static void w(Object object, {bool isRecovery = true}) => warning(object,isRecovery: isRecovery);

  static void e(Object object, {bool isRecovery = true}) => error(object, isRecovery: isRecovery);

  /// Standard
  static void verbose(Object object) => _dispatchLog(GTLoggerLevel.verbose, object, isRecovery: false);

  static void debug(Object object) => _dispatchLog(GTLoggerLevel.debug, object, isRecovery: false);

  static void info(Object object, {bool isRecovery = true}) => _dispatchLog(GTLoggerLevel.info, object, isRecovery: isRecovery);

  static void warning(Object object, {bool isRecovery = true}) => _dispatchLog(GTLoggerLevel.warning, object, isRecovery: isRecovery);

  static void error(Object object, {String? tag, bool isRecovery = true}) {
    String message = Error.safeToString(object).replaceAll("\"", "");
    if (object is FlutterError) {
      message = object.message;
    } else if (object is Error) {
      message = object.stackTrace.toString();
    }
    _dispatchLog(GTLoggerLevel.error, message, isRecovery: isRecovery);
  }

  /// 预处理日志，并且分发到不同的输出源
  static _dispatchLog(GTLoggerLevel level, Object message, {bool isRecovery = false}) {
    if (level.value < GTLogger.level.value) {
      return;
    }
    // 收集堆栈信息
    Map<String, String> stackTraceInfoMap = _getStackTrace();

    int lineNumber;
    try {
      lineNumber = stackTraceInfoMap['line'] == null ? 0 : int.parse(stackTraceInfoMap['line'] ?? '0');
    } catch (e) {
      lineNumber = 0;
    }

    GTLoggerModel logModel = GTLoggerModel(
        level,
        isRecovery,
        "$message",
        stackTraceInfoMap['file'] ?? 'Unknown file',
        stackTraceInfoMap['func'] ?? 'Unknown function',
        lineNumber);

    // 分发到不同的输出源
    for (var element in destinations) {
      element.receiveLog(logModel);
    }
  }

  /// 创建 GTLoggerModel，获取调试符号信息
  static Map<String, String> _getStackTrace() {
    var trace = StackTrace.current.toString().split('\n');

    String frame = trace.length > 4 ? trace[3].trim() : trace.last.trim();
    if (frame.contains('/gt_logger.dart')) {
      frame = trace.length > 5 ? trace[4].trim() : trace.last.trim();
    }

    // 使用空格分割输入字符串
    final reg = RegExp(r'#[0-9]+\s(.*)\s\((package:.*dart):([0-9]*).*\)');
    final match = reg.firstMatch(frame);

    // 提取文件信息、代码行数和方法名
    final func = match?[1] ?? 'Unknown function';
    final file = match?[2]?.replaceAll("package:", "") ?? 'Unknown file';
    final line = match?[3] ?? 'Unknown line';
    return {'file': file.trim(), 'func': func.trim(), 'line': line.trim()};
  }
}
